package com.tzstcl.framework.shiro;


import com.tzstcl.framework.constants.AppConstants;
import com.tzstcl.framework.redis.RedisService;
import com.tzstcl.sys.user.model.SysDept;
import com.tzstcl.sys.user.model.SysDeptPost;
import com.tzstcl.sys.user.model.SysPost;
import com.tzstcl.sys.user.model.SysUser;
import com.tzstcl.sys.user.service.SysDeptService;
import com.tzstcl.sys.user.service.SysUserService;
import com.tzstcl.sys.user.service.impl.SysDeptPostService;
import com.tzstcl.sys.user.service.impl.SysPostService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.Set;


/**
 * 认证
 *
 * @author haocj
 */
@Component
public class UserRealm extends AuthorizingRealm {

    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private SysDeptPostService sysDeptPostService;
    @Autowired
    private SysDeptService sysDeptService;
    @Autowired
    private SysPostService sysPostService;

    /**
     * 授权(验证权限时调用)
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SysUser user = (SysUser) principals.getPrimaryPrincipal();

        Set<String> set = null;

        set = (Set<String>) redisService.get(AppConstants.USER_PERMISSION_CACHE + user.getLoginName());

        if (set == null) {
            set = sysUserService.queryPermissions(user.getId());
            redisService.set(AppConstants.USER_PERMISSION_CACHE + user.getLoginName(), set);
        }
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //判断是否是管理员
        Set<String> roleSet = null;
        if(AppConstants.SUPER_ADMIN_Name.equals(user.getLoginName())){
            roleSet= new HashSet<String>();
            roleSet.add(AppConstants.SUPER_ADMIN_Name);
            set.add("*:*"); //添加所有权限
        }
        info.setRoles(roleSet);   //添加角色
        info.setStringPermissions(set);//添加权限
        return info;
    }

    /**
     * 认证(登录时调用)
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken token) throws AuthenticationException {
        String loginName = (String) token.getPrincipal();
        String password = new String((char[]) token.getCredentials());

        SysUser sysUser = null;

        //查询用户信息
        sysUser = new SysUser();
        sysUser.setLoginName(loginName);
        SysUser user = sysUserService.findByNameOrPass(sysUser);

        //账号不存在
        if (user == null) {
            throw new UnknownAccountException("账号或密码不正确");
        }

        //密码错误
        if (!password.equals(user.getPassword())) {
            throw new IncorrectCredentialsException("账号或密码不正确");
        }

        SysDeptPost sysDeptPost = sysDeptPostService.get(user.getId());

        if (sysDeptPost != null) {
            SysPost post = new SysPost();
            post.setId(sysDeptPost.getPostId());

            SysPost sysPost = sysPostService.getOne(sysDeptPost.getPostId());
            if (sysPost != null) {
                user.setPost(sysPost);
                user.setPostId(sysPost.getId());
            }

            SysDept dept = new SysDept();
            dept.setId(sysDeptPost.getDeptId());

            SysDept sysDept = sysDeptService.getOne(sysDeptPost.getDeptId());
            if (sysDept != null) {
                user.setDept(sysDept);
                user.setDeptId(sysDept.getId());
            }
        }

        Set<String> set = sysUserService.queryPermissions(user.getId());

        // 用户登录缓存用户信息
        redisService.set(AppConstants.USER_CACHE + user.getLoginName(), user);
        // 缓存用户权限信息
        redisService.set(AppConstants.USER_PERMISSION_CACHE + user.getLoginName(), set);

        // 把当前用户放入到session中
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession(true);
//        session.setTimeout(-100000);
        session.setAttribute(AppConstants.CURRENT_USER, user);

        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());
        return info;
    }

    /**
     * 清理缓存权限
     */
    public void clearCachedAuthorizationInfo() {
        this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
    }

}
